package com.hyz.yuaiagent.rag.document;

import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.markdown.MarkdownDocumentReader;
import org.springframework.ai.reader.markdown.config.MarkdownDocumentReaderConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 01- 读取本地文件 DocumentReader 这里是读取markdown文件  做Rag的第一步
 * 用于加载LoveApp文档的组件
 * 该组件通过指定的资源解析器加载类路径下的Markdown文档，并将其转换为Document对象集合
 */
@Component
@Slf4j
public class LoveAppDocumentLoader {

    // 用于解析资源位置模式的策略接口
    private final ResourcePatternResolver resourcePatternResolver;

    /**
     * 构造函数注入资源解析器
     *
     * @param resourcePatternResolver 资源解析器，用于解析类路径下的资源
     */
    @Autowired
    public LoveAppDocumentLoader(ResourcePatternResolver resourcePatternResolver) {
        this.resourcePatternResolver = resourcePatternResolver;
    }

    /**
     * 加载文档的方法
     * 该方法扫描类路径下的Markdown文档，并根据特定配置将其内容加载到Document对象列表中
     */
    public List<Document> loaderDocument() {
        ArrayList<Document> allDocuments = new ArrayList<>();
        try {
            // 获取类路径下所有匹配的Markdown资源
            Resource[] resources = resourcePatternResolver.getResources("classpath:/document/*.md");

            // 遍历每个资源，配置并读取Markdown文档内容
            for (Resource resource : resources) {
                String fileName = resource.getFilename();
                // 提取文档倒数第 3 和第 2 个字作为标签
                String status = fileName.substring(fileName.length() - 6, fileName.length() - 4);
                // 配置Markdown文档读取器，指定如何处理文档中的不同元素
                // 使用构建器模式创建MarkdownDocumentReaderConfig实例
                MarkdownDocumentReaderConfig config = MarkdownDocumentReaderConfig.builder()
                        // 设置是否将水平分割线视为新文档的开始，默认为false。这里设置为true。
                        .withHorizontalRuleCreateDocument(false)
                        // 设置是否包含代码块内容，默认为true。这里设置为false，表示不包括代码块。
                        .withIncludeCodeBlock(false)
                        // 设置是否包含引用块（blockquote）内容，默认为true。这里设置为false，表示不包括引用块。
                        .withIncludeBlockquote(false)
                        // 添加额外的元数据，这里是文件名。键为"fileName"，值为当前处理的Markdown文件名。
                        .withAdditionalMetadata("fileName", fileName)
                        // 完成配置并构建MarkdownDocumentReaderConfig对象
                        .withAdditionalMetadata("status", status)
                        .build();
                // 创建Markdown文档读取器实例，用于读取当前资源的Markdown文档
                MarkdownDocumentReader reader = new MarkdownDocumentReader(resource, config);

                // 将读取到的文档内容添加到文档列表中
                allDocuments.addAll(reader.get());
            }
            log.info("加载的文档:{}", allDocuments);
            return allDocuments;
        } catch (IOException e) {
            // 日志记录文档加载失败的错误信息
            log.error("MarkDocument文件加载失败:", e);
            return new ArrayList<>();
        }

    }
}
